<?php
declare(strict_types=1);

namespace Zms\Sms\Drive;

use Zms\Sms\Drive\Config\Alconfig;
use Zms\Sms\SmsResult;
use Zms\Request\Http;
use Zms\Unit\Json;

/**
 * 阿里云短息接口
 */
class Alsms extends SmsBasics
{

    /**
     * 阿里云不支持获取短信余额
     * 获取短信余额
     * @return int
     */
    public function getBalance(): int
    {
        return -1;
    }

    /**
     * 获取短信配置
     * @return Alconfig
     */
    protected function getConfig(): Alconfig
    {
        return parent::getConfig(); // TODO: Change the autogenerated stub
    }


    /**
     * 发送短信
     * @param string $phone
     * @param string $template_key
     * @param array $data
     * @return SmsResult
     */
    public function send(string $phone, string $template_key, array $data = []): SmsResult
    {

        $conf = $this->getConfig();
        $params = [//此处作了修改
            'SignName' => $conf->signature,
            'Format' => 'JSON',
            'Version' => '2017-05-25',
            'AccessKeyId' => $conf->AccessKeyId,
            'SignatureVersion' => '1.0',
            'SignatureMethod' => 'HMAC-SHA1',
            'SignatureNonce' => uniqid(),
            'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
            'Action' => 'SendSms',
            'TemplateCode' => $this->getTemplateCode($template_key, $conf->template),
            'PhoneNumbers' => $phone,
            'TemplateParam' => count($data) === 0 ? "{}" : json_encode($data)//请求参数
        ];
        $params ['Signature'] = $this->computeSignature($params, $conf->AccessKeySecret);


        $request = Http::instance()->execute($conf->host, $params)->jsonToArray();
        $content = $this->renderContent($conf->template, $template_key, array_merge($data, ['signature' => $conf->signature]));
        if ($request) {
            if ($request['Message'] === 'OK') {
                return new SmsResult(['phone' => $phone, 'content' => $content, 'status' => true, 'driver' => static::class, 'template_key' => $template_key, 'request' => $request]);
            }
        }
        return new SmsResult(['phone' => $phone, 'content' => $content, 'status' => false, 'driver' => static::class, 'template_key' => $template_key, 'request' => $request]);
    }


    /**
     * 获取模板ID
     * @param string $template_key
     * @param array $template
     * @return string
     */
    private function getTemplateCode(string $template_key, array $template): string
    {
        foreach ($template as $item) {
            if ($item['KEY'] === $template_key) {
                return $item['TEMPLATE_ID'];
            }
        }
        return '';
    }


    /**
     * 短信签名
     * @param array $parameters
     * @param string $accessKeySecret
     * @return string
     */
    private function computeSignature(array $parameters, string $accessKeySecret): string
    {
        ksort($parameters);
        $canonicalizedQueryString = '';
        foreach ($parameters as $key => $value) {
            $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
        }
        $stringToSign = 'GET&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
        return base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . '&', true));
    }

    /**
     * 格式化参数
     * @param string $string
     * @return string
     */
    private function percentEncode(string $string): string
    {
        $string = urlencode($string);
        $string = preg_replace('/\+/', '%20', $string);
        $string = preg_replace('/\*/', '%2A', $string);
        return preg_replace('/%7E/', '~', $string);
    }
}